//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package org_member_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas/api-server/api_common"
	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/org_dao"
	"atomgit.com/openlinksaas/api-server/dao/user_dao"
	"atomgit.com/openlinksaas/proto-gen-go.git/notices/notices_org"
	"atomgit.com/openlinksaas/proto-gen-go.git/org_asset_api"
	"atomgit.com/openlinksaas/proto-gen-go.git/org_member_api"
	"github.com/dchest/uniuri"
	"go.mongodb.org/mongo-driver/mongo"
)

type OrgMemberApiImpl struct {
	org_member_api.UnimplementedOrgMemberApiServer
}

func (apiImpl *OrgMemberApiImpl) GenInvite(ctx context.Context, req *org_member_api.GenInviteRequest) (*org_member_api.GenInviteResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.GenInviteResponse{
			Code:   org_member_api.GenInviteResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_member_api.GenInviteResponse{
			Code:   org_member_api.GenInviteResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	if orgItem.OwnerUserId != sessionItem.UserId {
		return &org_member_api.GenInviteResponse{
			Code:   org_member_api.GenInviteResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	if req.Ttl < 1 {
		req.Ttl = 1
	}
	if req.Ttl > 24*30 {
		req.Ttl = 24 * 30
	}

	inviteCode := "ORG" + uniuri.NewLen(61)
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.InviteDao.Insert(sessCtx, &org_dao.InviteInfoDbItem{
			InviteCode:   inviteCode,
			OrgId:        req.OrgId,
			CreateUserId: sessionItem.UserId,
			CreateTime:   time.Now().UnixNano() / 1e6,
			ExpireTime:   time.Now().Add(time.Duration(req.Ttl)*time.Hour).UnixNano() / 1e6,
		})
		if err != nil {
			return nil, err
		}
		return &org_member_api.GenInviteResponse{
			Code:       org_member_api.GenInviteResponse_CODE_OK,
			InviteCode: inviteCode,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*org_member_api.GenInviteResponse), nil
}

func (apiImpl *OrgMemberApiImpl) ListInvite(ctx context.Context, req *org_member_api.ListInviteRequest) (*org_member_api.ListInviteResponse, error) {
	emptyList := []*org_member_api.InviteInfo{}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.ListInviteResponse{
			Code:           org_member_api.ListInviteResponse_CODE_WRONG_SESSION,
			ErrMsg:         "会话不存在",
			InviteInfoList: emptyList,
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_member_api.ListInviteResponse{
			Code:           org_member_api.ListInviteResponse_CODE_NO_ORG,
			ErrMsg:         "组织不存在",
			InviteInfoList: emptyList,
		}, nil
	}
	if orgItem.OwnerUserId != sessionItem.UserId {
		return &org_member_api.ListInviteResponse{
			Code:           org_member_api.ListInviteResponse_CODE_NO_PERMISSION,
			ErrMsg:         "没有权限",
			InviteInfoList: emptyList,
		}, nil
	}

	//清除过期的邀请
	err = org_dao.InviteDao.RemoveExpire(ctx, req.OrgId, time.Now().UnixNano()/1e6)
	if err != nil {
		return nil, err
	}

	count, err := org_dao.InviteDao.Count(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}
	inviteItemList, err := org_dao.InviteDao.List(ctx, req.OrgId, int64(req.Offset), int64(req.Limit))
	if err != nil {
		return nil, err
	}

	//补全用户信息
	userIdList := []string{}
	for _, inviteItem := range inviteItemList {
		userIdList = append(userIdList, inviteItem.CreateUserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}

	//生成结果
	inviteList := []*org_member_api.InviteInfo{}
	for _, inviteItem := range inviteItemList {
		invite := inviteItem.ToInviteInfo()
		createUser, ok := userItemMap[inviteItem.CreateUserId]
		if ok {
			invite.CreateDisplayName = createUser.BasicInfo.DisplayName
			invite.CreateLogoUri = createUser.BasicInfo.LogoUri
		}
		inviteList = append(inviteList, invite)
	}
	return &org_member_api.ListInviteResponse{
		Code:           org_member_api.ListInviteResponse_CODE_OK,
		TotalCount:     count,
		InviteInfoList: inviteList,
	}, nil
}

func (apiImpl *OrgMemberApiImpl) RemoveInvite(ctx context.Context, req *org_member_api.RemoveInviteRequest) (*org_member_api.RemoveInviteResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.RemoveInviteResponse{
			Code:   org_member_api.RemoveInviteResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_member_api.RemoveInviteResponse{
			Code:   org_member_api.RemoveInviteResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	if orgItem.OwnerUserId != sessionItem.UserId {
		return &org_member_api.RemoveInviteResponse{
			Code:   org_member_api.RemoveInviteResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.InviteDao.Remove(sessCtx, req.OrgId, req.InviteCode)
		if err != nil {
			return nil, err
		}
		return &org_member_api.RemoveInviteResponse{
			Code: org_member_api.RemoveInviteResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*org_member_api.RemoveInviteResponse), nil
}

func (apiImpl *OrgMemberApiImpl) Join(ctx context.Context, req *org_member_api.JoinRequest) (*org_member_api.JoinResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.JoinResponse{
			Code:   org_member_api.JoinResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	//检查invite code
	inviteItem, err := org_dao.InviteDao.Get(ctx, req.InviteCode)
	if err != nil {
		return &org_member_api.JoinResponse{
			Code:   org_member_api.JoinResponse_CODE_WRONG_INVITE_CODE,
			ErrMsg: "错误的邀请码",
		}, nil
	}
	nowTime := time.Now().UnixNano() / 1e6
	if inviteItem.ExpireTime < nowTime {
		return &org_member_api.JoinResponse{
			Code:   org_member_api.JoinResponse_CODE_WRONG_INVITE_CODE,
			ErrMsg: "错误的邀请码",
		}, nil
	}
	//检查组织是否存在
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, inviteItem.OrgId)
	if err != nil {
		return &org_member_api.JoinResponse{
			Code:   org_member_api.JoinResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.MemberDao.Insert(sessCtx, &org_dao.MemberInfoDbItem{
			OrgId:              inviteItem.OrgId,
			MemberUserId:       sessionItem.UserId,
			ParentDepartMentId: orgItem.NewMemberDepartMentId,
			CreateTime:         nowTime,
			MemberPermInfo: org_dao.MemberPermInfoDbItem{
				ManageDepartMentPerm:     false,
				ManageAssetCate:          false,
				ManageAllAsset:           false,
				ManageDepartMentAsset:    false,
				ManageSelfAsset:          false,
				ManageEvaluateTarget:     false,
				ViewAllEvaluate:          false,
				ManageDepartMentEvaluate: false,
			},
		})
		if err != nil {
			return nil, err
		}
		count, err := org_dao.MemberDao.CountByDepartment(sessCtx, inviteItem.OrgId, orgItem.NewMemberDepartMentId)
		if err != nil {
			return nil, err
		}
		err = org_dao.DepartMentDao.UpdateSubMemberCount(sessCtx, inviteItem.OrgId, orgItem.NewMemberDepartMentId, count)
		if err != nil {
			return nil, err
		}
		//更新组织计数
		count, err = org_dao.MemberDao.CountByOrg(sessCtx, inviteItem.OrgId)
		if err != nil {
			return nil, err
		}
		err = org_dao.OrgInfoDao.UpdateMemberCount(sessCtx, inviteItem.OrgId, count)
		if err != nil {
			return nil, err
		}
		return &org_member_api.JoinResponse{
			Code:  org_member_api.JoinResponse_CODE_OK,
			OrgId: inviteItem.OrgId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go api_common.SendNoticeToOrgScope(context.Background(), inviteItem.OrgId, &notices_org.JoinOrgNotice{
		OrgId:        inviteItem.OrgId,
		MemberUserId: sessionItem.UserId,
	})
	go api_common.SendNoticeToOrgScope(context.Background(), inviteItem.OrgId, &notices_org.UpdateDepartMentNotice{
		OrgId:        inviteItem.OrgId,
		DepartMentId: orgItem.NewMemberDepartMentId,
	})
	return ret.(*org_member_api.JoinResponse), nil
}

// linksaas://comment/4MiKn4YF3vcMjFCicHvtI
func (apiImpl *OrgMemberApiImpl) Leave(ctx context.Context, req *org_member_api.LeaveRequest) (*org_member_api.LeaveResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.LeaveResponse{
			Code:   org_member_api.LeaveResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_member_api.LeaveResponse{
			Code:   org_member_api.LeaveResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	if orgItem.OwnerUserId == sessionItem.UserId {
		return &org_member_api.LeaveResponse{
			Code:   org_member_api.LeaveResponse_CODE_NOT_ALLOW,
			ErrMsg: "管理员不能退出组织",
		}, nil
	}
	curMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_member_api.LeaveResponse{
			Code: org_member_api.LeaveResponse_CODE_OK,
		}, nil
	}

	memberItemList, err := org_dao.MemberDao.ListByOrg(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}

	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.MemberDao.Remove(sessCtx, req.OrgId, sessionItem.UserId)
		if err != nil {
			return nil, err
		}
		if curMemberItem.ParentDepartMentId != "" {
			count, err := org_dao.MemberDao.CountByDepartment(sessCtx, req.OrgId, curMemberItem.ParentDepartMentId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateSubMemberCount(sessCtx, req.OrgId, curMemberItem.ParentDepartMentId, count)
			if err != nil {
				return nil, err
			}
		}
		//更新组织计数
		count, err := org_dao.MemberDao.CountByOrg(sessCtx, req.OrgId)
		if err != nil {
			return nil, err
		}
		err = org_dao.OrgInfoDao.UpdateMemberCount(sessCtx, req.OrgId, count)
		if err != nil {
			return nil, err
		}
		//个人资产变成部门资产
		assetItemList, err := org_dao.AssetDao.ListByMember(sessCtx, req.OrgId, []string{sessionItem.UserId})
		if err != nil {
			return nil, err
		}
		for _, assetItem := range assetItemList {
			err = org_dao.AssetDao.UpdateOwner(sessCtx, req.OrgId, assetItem.AssetId, uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT), curMemberItem.ParentDepartMentId, sessionItem.UserId, nowTime)
			if err != nil {
				return nil, err
			}
		}
		if curMemberItem.ParentDepartMentId != "" {
			count, err = org_dao.AssetDao.CountByDepartMent(sessCtx, req.OrgId, curMemberItem.ParentDepartMentId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateAssetCount(sessCtx, req.OrgId, curMemberItem.ParentDepartMentId, count)
			if err != nil {
				return nil, err
			}
		}

		return &org_member_api.LeaveResponse{
			Code: org_member_api.LeaveResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go func() {
		for _, memberItem := range memberItemList {
			api_common.SendNoticeToUser(context.Background(), memberItem.MemberUserId, &notices_org.LeaveOrgNotice{
				OrgId:        req.OrgId,
				MemberUserId: sessionItem.UserId,
			})
			if curMemberItem.ParentDepartMentId != "" {
				api_common.SendNoticeToUser(context.Background(), memberItem.MemberUserId, &notices_org.UpdateDepartMentNotice{
					OrgId:        req.OrgId,
					DepartMentId: curMemberItem.ParentDepartMentId,
				})
			}
		}
	}()

	return ret.(*org_member_api.LeaveResponse), nil
}

// linksaas://comment/RGrbieoTTtHyKCPkMtP3P
func (apiImpl *OrgMemberApiImpl) RemoveMember(ctx context.Context, req *org_member_api.RemoveMemberRequest) (*org_member_api.RemoveMemberResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.RemoveMemberResponse{
			Code:   org_member_api.RemoveMemberResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_member_api.RemoveMemberResponse{
			Code:   org_member_api.RemoveMemberResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	if orgItem.OwnerUserId != sessionItem.UserId {
		return &org_member_api.RemoveMemberResponse{
			Code:   org_member_api.RemoveMemberResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	if orgItem.OwnerUserId == req.MemberUserId { //不能删除管理员
		return &org_member_api.RemoveMemberResponse{
			Code:   org_member_api.RemoveMemberResponse_CODE_NOT_ALLOW,
			ErrMsg: "不能删除管理员",
		}, nil
	}

	targetMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, req.MemberUserId)
	if err != nil {
		return &org_member_api.RemoveMemberResponse{
			Code: org_member_api.RemoveMemberResponse_CODE_OK,
		}, nil
	}

	memberItemList, err := org_dao.MemberDao.ListByOrg(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}

	nowTime := time.Now().UnixNano() / 1e6

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.MemberDao.Remove(sessCtx, req.OrgId, req.MemberUserId)
		if err != nil {
			return nil, err
		}
		if targetMemberItem.ParentDepartMentId != "" {
			count, err := org_dao.MemberDao.CountByDepartment(sessCtx, req.OrgId, targetMemberItem.ParentDepartMentId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateSubMemberCount(sessCtx, req.OrgId, targetMemberItem.ParentDepartMentId, count)
			if err != nil {
				return nil, err
			}
		}
		//更新组织计数
		count, err := org_dao.MemberDao.CountByOrg(sessCtx, req.OrgId)
		if err != nil {
			return nil, err
		}
		err = org_dao.OrgInfoDao.UpdateMemberCount(sessCtx, req.OrgId, count)
		if err != nil {
			return nil, err
		}
		//个人资产变成部门资产
		assetItemList, err := org_dao.AssetDao.ListByMember(sessCtx, req.OrgId, []string{req.MemberUserId})
		if err != nil {
			return nil, err
		}
		for _, assetItem := range assetItemList {
			err = org_dao.AssetDao.UpdateOwner(sessCtx, req.OrgId, assetItem.AssetId, uint32(org_asset_api.ASSET_OWNER_TYPE_ASSET_OWNER_DEPART_MENT), targetMemberItem.ParentDepartMentId, sessionItem.UserId, nowTime)
			if err != nil {
				return nil, err
			}
		}
		if targetMemberItem.ParentDepartMentId != "" {
			count, err = org_dao.AssetDao.CountByDepartMent(sessCtx, req.OrgId, targetMemberItem.ParentDepartMentId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateAssetCount(sessCtx, req.OrgId, targetMemberItem.ParentDepartMentId, count)
			if err != nil {
				return nil, err
			}
		}
		return &org_member_api.RemoveMemberResponse{
			Code: org_member_api.RemoveMemberResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go func() {
		for _, memberItem := range memberItemList {
			api_common.SendNoticeToUser(context.Background(), memberItem.MemberUserId, &notices_org.LeaveOrgNotice{
				OrgId:        req.OrgId,
				MemberUserId: req.MemberUserId,
			})
			if targetMemberItem.ParentDepartMentId != "" {
				api_common.SendNoticeToUser(context.Background(), memberItem.MemberUserId, &notices_org.UpdateDepartMentNotice{
					OrgId:        req.OrgId,
					DepartMentId: targetMemberItem.ParentDepartMentId,
				})
			}
		}
	}()
	return ret.(*org_member_api.RemoveMemberResponse), nil
}

func (apiImpl *OrgMemberApiImpl) MoveMember(ctx context.Context, req *org_member_api.MoveMemberRequest) (*org_member_api.MoveMemberResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.MoveMemberResponse{
			Code:   org_member_api.MoveMemberResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_member_api.MoveMemberResponse{
			Code:   org_member_api.MoveMemberResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}
	if orgItem.OwnerUserId != sessionItem.UserId {
		return &org_member_api.MoveMemberResponse{
			Code:   org_member_api.MoveMemberResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	memberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, req.MemberUserId)
	if err != nil {
		return &org_member_api.MoveMemberResponse{
			Code: org_member_api.MoveMemberResponse_CODE_OK,
		}, nil
	}
	if memberItem.ParentDepartMentId == req.ParentDepartMentId { //不需要移动
		return &org_member_api.MoveMemberResponse{
			Code: org_member_api.MoveMemberResponse_CODE_OK,
		}, nil
	}

	if req.ParentDepartMentId != "" {
		exist, err := org_dao.DepartMentDao.Exist(ctx, req.OrgId, req.ParentDepartMentId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &org_member_api.MoveMemberResponse{
				Code:   org_member_api.MoveMemberResponse_CODE_NO_DEPART_MENT,
				ErrMsg: "目标部门不存在",
			}, nil
		}
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.MemberDao.UpdateDepartment(sessCtx, req.OrgId, req.MemberUserId, req.ParentDepartMentId)
		if err != nil {
			return nil, err
		}
		if memberItem.ParentDepartMentId != "" {
			count, err := org_dao.MemberDao.CountByDepartment(sessCtx, req.OrgId, memberItem.ParentDepartMentId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateSubMemberCount(sessCtx, req.OrgId, memberItem.ParentDepartMentId, count)
			if err != nil {
				return nil, err
			}
		}
		if req.ParentDepartMentId != "" {
			count, err := org_dao.MemberDao.CountByDepartment(sessCtx, req.OrgId, req.ParentDepartMentId)
			if err != nil {
				return nil, err
			}
			err = org_dao.DepartMentDao.UpdateSubMemberCount(sessCtx, req.OrgId, req.ParentDepartMentId, count)
			if err != nil {
				return nil, err
			}
		}
		return &org_member_api.MoveMemberResponse{
			Code: org_member_api.MoveMemberResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go api_common.SendNoticeToOrgScope(context.Background(), req.OrgId, &notices_org.UpdateMemberNotice{
		OrgId:        req.OrgId,
		MemberUserId: req.MemberUserId,
	})
	if memberItem.ParentDepartMentId != "" {
		go api_common.SendNoticeToOrgScope(context.Background(), req.OrgId, &notices_org.UpdateDepartMentNotice{
			OrgId:        req.OrgId,
			DepartMentId: memberItem.ParentDepartMentId,
		})
	}
	if req.ParentDepartMentId != "" {
		go api_common.SendNoticeToOrgScope(context.Background(), req.OrgId, &notices_org.UpdateDepartMentNotice{
			OrgId:        req.OrgId,
			DepartMentId: req.ParentDepartMentId,
		})
	}
	return ret.(*org_member_api.MoveMemberResponse), nil
}

func (apiImpl *OrgMemberApiImpl) ListMember(ctx context.Context, req *org_member_api.ListMemberRequest) (*org_member_api.ListMemberResponse, error) {
	emptyList := []*org_member_api.MemberInfo{}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.ListMemberResponse{
			Code:       org_member_api.ListMemberResponse_CODE_WRONG_SESSION,
			ErrMsg:     "会话不存在",
			MemberList: emptyList,
		}, nil
	}
	exist, err := org_dao.OrgInfoDao.Exist(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_member_api.ListMemberResponse{
			Code:       org_member_api.ListMemberResponse_CODE_NO_ORG,
			ErrMsg:     "组织不存在",
			MemberList: emptyList,
		}, nil
	}

	exist, err = org_dao.MemberDao.Exist(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_member_api.ListMemberResponse{
			Code:       org_member_api.ListMemberResponse_CODE_NO_PERMISSION,
			ErrMsg:     "没有权限",
			MemberList: emptyList,
		}, nil
	}
	memberItemList, err := org_dao.MemberDao.ListByOrg(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}

	departMentItemList, err := org_dao.DepartMentDao.ListByOrg(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}

	departMentItemMap := map[string]*org_dao.DepartMentInfoDbItem{}
	for _, departMentItem := range departMentItemList {
		departMentItemMap[departMentItem.DepartMentId] = departMentItem
	}

	//补全用户信息
	userIdList := []string{}
	for _, memberItem := range memberItemList {
		userIdList = append(userIdList, memberItem.MemberUserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}
	//获取简历访问权限
	accessItemList, err := user_dao.ResumeAccessDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	accessItemMap := map[string]*user_dao.ResumeAccessDbItem{}
	for _, accessItem := range accessItemList {
		accessItemMap[accessItem.UserId] = accessItem
	}
	//生成结果
	memberList := []*org_member_api.MemberInfo{}
	for _, memberItem := range memberItemList {
		member := memberItem.ToMemberInfo()
		userItem, ok := userItemMap[memberItem.MemberUserId]
		if ok {
			member.DisplayName = userItem.BasicInfo.DisplayName
			member.LogoUri = userItem.BasicInfo.LogoUri
		}
		accessItem, ok := accessItemMap[memberItem.MemberUserId]
		if ok {
			member.HasResume = accessItem.AllowOrgAccess
		}
		member.DepartMentIdPath = apiImpl.calcDepartMentPath(departMentItemMap, memberItem.ParentDepartMentId)
		memberList = append(memberList, member)
	}

	return &org_member_api.ListMemberResponse{
		Code:       org_member_api.ListMemberResponse_CODE_OK,
		MemberList: memberList,
	}, nil
}

func (apiImpl *OrgMemberApiImpl) GetMember(ctx context.Context, req *org_member_api.GetMemberRequest) (*org_member_api.GetMemberResponse, error) {
	emptyInfo := &org_member_api.MemberInfo{
		DepartMentIdPath: []string{},
	}

	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.GetMemberResponse{
			Code:   org_member_api.GetMemberResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
			Member: emptyInfo,
		}, nil
	}
	exist, err := org_dao.OrgInfoDao.Exist(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_member_api.GetMemberResponse{
			Code:   org_member_api.GetMemberResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
			Member: emptyInfo,
		}, nil
	}

	exist, err = org_dao.MemberDao.Exist(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &org_member_api.GetMemberResponse{
			Code:   org_member_api.GetMemberResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
			Member: emptyInfo,
		}, nil
	}

	memberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, req.MemberUserId)
	if err != nil {
		return &org_member_api.GetMemberResponse{
			Code:   org_member_api.GetMemberResponse_CODE_NO_MEMBER,
			ErrMsg: "组织成员不存在",
			Member: emptyInfo,
		}, nil
	}

	departMentItemList, err := org_dao.DepartMentDao.ListByOrg(ctx, req.OrgId)
	if err != nil {
		return nil, err
	}

	departMentItemMap := map[string]*org_dao.DepartMentInfoDbItem{}
	for _, departMentItem := range departMentItemList {
		departMentItemMap[departMentItem.DepartMentId] = departMentItem
	}

	//补全用户信息
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, []string{req.MemberUserId})
	if err != nil {
		return nil, err
	}

	accessItemList, err := user_dao.ResumeAccessDao.ListById(ctx, []string{req.MemberUserId})
	if err != nil {
		return nil, err
	}
	//生成结果
	member := memberItem.ToMemberInfo()
	if len(userItemList) == 1 {
		member.DisplayName = userItemList[0].BasicInfo.DisplayName
		member.LogoUri = userItemList[0].BasicInfo.LogoUri
	}
	if len(accessItemList) == 1 {
		member.HasResume = accessItemList[0].AllowOrgAccess
	}
	member.DepartMentIdPath = apiImpl.calcDepartMentPath(departMentItemMap, memberItem.ParentDepartMentId)

	return &org_member_api.GetMemberResponse{
		Code:   org_member_api.GetMemberResponse_CODE_OK,
		Member: member,
	}, nil
}

// linksaas://comment/GLvpt7JdrnMxwRnnys9P9
func (apiImpl *OrgMemberApiImpl) UpdateMemberPerm(ctx context.Context, req *org_member_api.UpdateMemberPermRequest) (*org_member_api.UpdateMemberPermResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &org_member_api.UpdateMemberPermResponse{
			Code:   org_member_api.UpdateMemberPermResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	orgItem, err := org_dao.OrgInfoDao.Get(ctx, req.OrgId)
	if err != nil {
		return &org_member_api.UpdateMemberPermResponse{
			Code:   org_member_api.UpdateMemberPermResponse_CODE_NO_ORG,
			ErrMsg: "组织不存在",
		}, nil
	}

	selfMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, sessionItem.UserId)
	if err != nil {
		return &org_member_api.UpdateMemberPermResponse{
			Code:   org_member_api.UpdateMemberPermResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	if !(orgItem.OwnerUserId == sessionItem.UserId || selfMemberItem.MemberPermInfo.ManageDepartMentPerm) {
		return &org_member_api.UpdateMemberPermResponse{
			Code:   org_member_api.UpdateMemberPermResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	targetMemberItem, err := org_dao.MemberDao.Get(ctx, req.OrgId, req.MemberUserId)
	if err != nil {
		return &org_member_api.UpdateMemberPermResponse{
			Code:   org_member_api.UpdateMemberPermResponse_CODE_NO_MEMBER,
			ErrMsg: "团队成员不存在",
		}, nil
	}
	if orgItem.OwnerUserId != sessionItem.UserId { //非管理员
		if selfMemberItem.ParentDepartMentId != targetMemberItem.ParentDepartMentId {
			return &org_member_api.UpdateMemberPermResponse{
				Code:   org_member_api.UpdateMemberPermResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}, nil
		}
		//调整权限
		req.MemberPermInfo.ManageAssetCate = targetMemberItem.MemberPermInfo.ManageAssetCate
		req.MemberPermInfo.ManageAllAsset = targetMemberItem.MemberPermInfo.ManageAllAsset
		req.MemberPermInfo.ManageEvaluateTarget = targetMemberItem.MemberPermInfo.ManageEvaluateTarget
		req.MemberPermInfo.ViewAllEvaluate = targetMemberItem.MemberPermInfo.ViewAllEvaluate
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = org_dao.MemberDao.UpdateMemberPerm(sessCtx, req.OrgId, req.MemberUserId, &org_dao.MemberPermInfoDbItem{
			ManageDepartMentPerm:     req.MemberPermInfo.ManageDepartMentPerm,
			ManageAssetCate:          req.MemberPermInfo.ManageAssetCate,
			ManageAllAsset:           req.MemberPermInfo.ManageAllAsset,
			ManageDepartMentAsset:    req.MemberPermInfo.ManageDepartMentAsset,
			ManageSelfAsset:          req.MemberPermInfo.ManageSelfAsset,
			ManageEvaluateTarget:     req.MemberPermInfo.ManageEvaluateTarget,
			ViewAllEvaluate:          req.MemberPermInfo.ViewAllEvaluate,
			ManageDepartMentEvaluate: req.MemberPermInfo.ManageDepartMentEvaluate,
		})
		if err != nil {
			return nil, err
		}
		return &org_member_api.UpdateMemberPermResponse{
			Code: org_member_api.UpdateMemberPermResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go api_common.SendNoticeToOrgScope(context.Background(), req.OrgId, &notices_org.UpdateMemberNotice{
		OrgId:        req.OrgId,
		MemberUserId: req.MemberUserId,
	})
	return ret.(*org_member_api.UpdateMemberPermResponse), nil
}

func (apiImpl *OrgMemberApiImpl) calcDepartMentPath(departMentItemMap map[string]*org_dao.DepartMentInfoDbItem, parentDepartMentId string) []string {
	tmpList := []string{}
	tmpDepartMentId := parentDepartMentId
	for i := 0; i < 99; i++ { //放在死循环
		tmpList = append(tmpList, tmpDepartMentId)
		if tmpDepartMentId == "" {
			break
		}
		tmpItem := departMentItemMap[tmpDepartMentId]
		if tmpItem == nil {
			break
		}
		tmpDepartMentId = tmpItem.ParentDepartMentId
	}
	retList := []string{}
	for i := len(tmpList) - 1; i >= 0; i-- {
		retList = append(retList, tmpList[i])
	}
	return retList
}
